package com.hejia.alauda.utils;


import static com.hejia.alauda.utils.Utils.formatDate;
import static com.hejia.alauda.utils.Utils.readValue;

import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;

import com.hejia.alauda.entity.Activity;
import com.hejia.alauda.entity.Parameter;
import com.hejia.alauda.service.CommonServiceImpl;
import com.hejia.alauda.service.ConfigureService;

public class ActivityUtils {

	private static final Map<String, JsonNode> ACTIVIFY = new HashMap<>();

	private static final Object LOCK = new Object();
	
	private static final String FOLDER = "/activity/";

	private static final String PROPERTIES = ".json";
	
	private static final String DATE_FORMAT = "yyyy-MM-dd";
	
	private static final ThreadLocal<SimpleDateFormat> LOCAL = new ThreadLocal<>();
	
	/**
	 * 获得当前配置
	 * @return
	 */
	public static Map<String,Object> getHushen300StepConfig() {
		String now = formatDate(Calendar.getInstance());
		ConfigureService configureService = CommonServiceImpl.applicationContext.getBean(ConfigureService.class);
		Parameter parameter = configureService.getParameter(Parameter.Category.Custom, "HUSHEN_300_CONFIG");
		List<Map<String,Object>> configs = (List<Map<String,Object>>) readValue(parameter.getValue(), List.class);
		Map<String,Object> nowConfig = configs.get(configs.size() - 1);
		for (int i = 0; i < configs.size(); i++) {
			Map<String, Object> item = configs.get(i);
			String weekStartDate = (String) item.get("WeekStartDate"), weekEndDate = (String) item
					.get("WeekEndDate");
			if (now.compareTo(weekStartDate) >= 0
					&& now.compareTo(weekEndDate) <= 0) {
				nowConfig = item;
			}
		}
		return nowConfig;
	}
	
	public static Map<String,Object> getHushen300PreviousConfig(Map<String,Object> nowConfig) {
		ConfigureService configureService = CommonServiceImpl.applicationContext.getBean(ConfigureService.class);
		Parameter parameter = configureService.getParameter(Parameter.Category.Custom, "HUSHEN_300_CONFIG");
		List<Map<String,Object>> configs = (List<Map<String,Object>>) readValue(parameter.getValue(), List.class);
		for (int i = 0; i < configs.size(); i++) {
			Map<String, Object> item = configs.get(i);
			if(item.get("WeekStartDate").toString().equals(nowConfig.get("WeekStartDate").toString())){
				return configs.get(i > 0 ? i - 1 : i);
			}
		}
		return configs.get(0);
	}
	/**
	 * 判断股神活动是否结束
	 * @return
	 */
	public static boolean isHushen300Expired(){
		String now = formatDate(Calendar.getInstance());
		ConfigureService configureService = CommonServiceImpl.applicationContext.getBean(ConfigureService.class);
		Parameter parameter = configureService.getParameter(Parameter.Category.Custom, "HUSHEN_300_CONFIG");
		List<Map<String,Object>> configs = (List<Map<String,Object>>) readValue(parameter.getValue(), List.class);
		String activityStartDate = (String) configs.get(0).get("WeekStartDate");
		String activityEndDate = (String) configs.get(configs.size() - 1).get("WeekEndDate");
		return !(now.compareTo(activityStartDate) >= 0
				&& now.compareTo(activityEndDate) <= 0);
	}

	// 获取奖品信息
	private static void getAwards(String activityName) {
		JsonNode nodes = ACTIVIFY.get(activityName);

		if (nodes == null) {
			synchronized (LOCK) {
				
				if (ACTIVIFY.get(activityName) != null)
					return;
				
				InputStream file = ActivityUtils.class.getResourceAsStream(FOLDER + activityName + PROPERTIES);

				try {
					int size = file.available();
					if (size == 0) {
					}
				} catch (IOException e) {
					throw new IllegalArgumentException("活动配置文件读取异常", e);
				}

				ObjectMapper mapper = new ObjectMapper();

				try {
					nodes = mapper.readTree(file);
					ACTIVIFY.put(activityName, nodes);
				} catch (IOException e) {
					throw new IllegalArgumentException("JSON 文件内容格式错误", e);
				}
			}
		}
	}
	
	public static String getName(String activityName, String award) {
		getAwards(activityName);
		
		return ACTIVIFY.get(activityName).findValue(award).findValue("award").getTextValue();
	}

	public static String getDescription(String activityName, String award) {
		getAwards(activityName);
		
		return ACTIVIFY.get(activityName).findValue(award).findValue("desc").getTextValue();
	}

	public static String getCondition(String activityName, String award) {
		getAwards(activityName);
		
		return ACTIVIFY.get(activityName).findValue(award).findValue("cond").getTextValue();
	}
	
	public static boolean isEntity(String activityName, String award) {
		getAwards(activityName);
		
		String entity = ACTIVIFY.get(activityName).findValue(award).findValue("entity").getTextValue();
		
		if (StringUtils.isNotEmpty(entity)) {
			if (entity.equals("true"))
				return true;
			else 
				return false;
		} else {
			return false;
		}
	}
	
	public static boolean isOnlyOne(String activityName, String award) {
		getAwards(activityName);
		
		String onlyOne = ACTIVIFY.get(activityName).findValue(award).findValue("onlyOne").getTextValue();
		
		if (StringUtils.isNotEmpty(onlyOne)) {
			if (onlyOne.equals("true"))
				return true;
			else 
				return false;
		} else {
			return false;
		}
	}

	/** 活动时间格式转换  */
	public static Date getDate(String activityName,String award) {
		getAwards(activityName);
		
		Date date = null;
		try {
			String str = getCondition(activityName, award);
			
			SimpleDateFormat mat = getDateFormat();
			
			date = mat.parse(str);
		} catch (ParseException e) {
			throw new IllegalArgumentException("配置文件时间格式错误", e);
		}
		return date;
	}
	
	public static SimpleDateFormat getDateFormat () {
		SimpleDateFormat mat = LOCAL.get();
		
		if (mat == null) {
			mat = new SimpleDateFormat(DATE_FORMAT);
			LOCAL.set(mat);
		}
		
		return mat;
	}
	
	/** 奖品当天发放数量  */
	public static int getTodayNumber(String activityName,String award) {
		getAwards(activityName);
		
		int allDays = DateUtil.getAllDays(activityName);
		int allNumber = Integer.valueOf(getCondition(activityName, award));

		// 当天平均数量
		int days = allNumber / allDays;
		// 平均天数的余数
		int residue = allNumber % allDays;
		
		if (residue != 0) {
			// 总天数减去余数 表示从活动开始几天后，每天平均数加一
			int start = allDays - residue;
			
			// 活动已经开始天数
			int startDays = DateUtil.getStartDays(activityName);

			if (startDays >= start)
				days += 1;
		}

		return days;
	}
	
	/** 奖品当天发放数量  */
	public static int getTodayNumberByEachRound(String activityName,String award) {
		getAwards(activityName);
		
		int allDays = Integer.valueOf(getCondition(activityName, Activity.INTERVAL));
		int allNumber = Integer.valueOf(getCondition(activityName, award));
		
		// 当天平均数量
		int days = allNumber / allDays;
		// 平均天数的余数
		int residue = allNumber % allDays;
		
		if (residue != 0) {
			// 总天数减去余数 表示从活动开始几天后，每天平均数加一
			int start = allDays - residue;
			
			// 活动已经开始天数
			int startDays = DateUtil.getStartDays(activityName);
			
			if (startDays > allDays) {
				startDays = startDays % allDays;
			}
			
			if (startDays >= start)
				days += 1;
		}
		
		return days;
	}

	
	/** 时间间隔天数 */
	public static int intervalDays (String start,String end) {
		return DateUtil.intervalDays(start, end);
	}

	
	private static class DateUtil {

		// 每个活动的总天数记录
		static final Map<String,Integer> ALL_DAYS = new HashMap<>();
		
		static final Object LOCK_ = new Object();

		static int getAllDays(String activityName) {
			Integer days = ALL_DAYS.get(activityName);
			
			if (days == null) {
				synchronized (LOCK_) {
					String start,end;
					
					start = getCondition(activityName, "START_DATE");
					
					end = getCondition(activityName, "END_DATE");
					
					days = intervalDays(start,end);
					ALL_DAYS.put(activityName, days);
				}
			}
			
			return days;
		}

		static int getStartDays(String activityName) {
			
			String start,end;
			
			start = getCondition(activityName, "START_DATE");
			
			SimpleDateFormat mat = getDateFormat();
			
			end = mat.format(new Date());

			return intervalDays(start, end);
		}
		
		static int intervalDays (String start,String end) {
            long interval = 0 ;
            SimpleDateFormat mat = getDateFormat();
            
			try {
			    interval = mat.parse(end).getTime() - mat.parse(start).getTime();
			} catch (ParseException e) {
				e.printStackTrace();
			}

			return (int) (interval / (1000 * 60 * 60 * 24));
		}
	}

}
